from datetime import timedelta
from django.conf import settings
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer, TokenRefreshSerializer
from rest_framework.exceptions import ValidationError
from django_redis import get_redis_connection
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth import get_user_model

User = get_user_model()

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        # 判断是否启用验证码
        if getattr(settings, 'CAPTCHA_ENABLED', True):
            # 验证码校验：从请求中获取验证码相关字段
            captcha_key = self.initial_data.get("captchaKey")
            captcha_code = self.initial_data.get("captchaCode")
            if not captcha_key or not captcha_code:
                raise ValidationError("缺少验证码信息")

            redis_conn = get_redis_connection("default")
            stored_value = redis_conn.get(captcha_key)
            if not stored_value:
                raise ValidationError("用户验证码过期")

            # 比较验证码（忽略大小写）
            if captcha_code.lower() != stored_value.decode("utf-8").lower():
                raise ValidationError("验证码错误")

            # 校验成功后，为防止重复使用，删除验证码
            redis_conn.delete(captcha_key)

        # 在调用父类验证前先检查用户状态
        username = attrs.get('username')
        try:
            user = User.objects.get(username=username)
            # 检查用户状态，状态为0(禁用)时不允许登录
            if user.status == 0:
                raise ValidationError("用户已被禁用，请联系管理员")
            # 检查用户是否已被删除，is_deleted为1时不允许登录
            if user.is_deleted == 1:
                raise ValidationError("用户不存在或已被删除")
        except User.DoesNotExist:
            # 让父类方法处理用户不存在的情况
            pass

        # 调用父类进行用户名和密码校验
        data = super().validate(attrs)

        token_type = "Bearer"
        access_token = data.get("access")
        refresh_token = data.get("refresh")
        access_token_lifetime = settings.SIMPLE_JWT.get("ACCESS_TOKEN_LIFETIME", timedelta(minutes=5))
        expires_in = int(access_token_lifetime.total_seconds())

        return {
            "code": "00000",
            "data": {
                "tokenType": token_type,
                "accessToken": access_token,
                "refreshToken": refresh_token,
                "expiresIn": expires_in,
            },
            "msg": "一切ok"
        }


class CustomTokenRefreshSerializer(TokenRefreshSerializer):
    def validate(self, attrs):
        # 父类进行 refresh token 校验，生成新的 access token
        data = super().validate(attrs)

        # 这里我们直接返回传入的 refresh token（不进行刷新令牌更新，如需要刷新刷新令牌，可开启 refresh token 轮换）
        refresh = RefreshToken(attrs["refresh"])
        data["refresh"] = str(refresh)

        token_type = "Bearer"
        expires_in = int(settings.SIMPLE_JWT.get("ACCESS_TOKEN_LIFETIME").total_seconds())

        return {
            "code": "00000",
            "data": {
                "tokenType": token_type,
                "accessToken": data.get("access"),
                "refreshToken": data.get("refresh"),
                "expiresIn": expires_in,
            },
            "msg": "一切ok"
        }
